using System;
using NFreeMarker.Template;
using NUnit.Framework;

// ReSharper disable InconsistentNaming
namespace NFreeMarker.Tests.Template
{
    public class TemplateTests_ProcessBuiltinsForDates
    {
        [TestFixture]
        public class When_processing_a_date_builtin : TemplateTestsBase
        {
            [Test]
            public void Assure_the_long_date_representation_is_returned_for_a_DateTimeOffset()
            {
                SetTemplateContent("${value?date}");
                AddTemplateVariable("value", new DateTimeOffset(2000, 1, 2, 1, 2, 3, TimeSpan.Zero));

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("Sunday, January 02, 2000"));
            }

            [Test]
            public void Assure_the_long_date_representation_is_returned_for_a_date()
            {
                SetTemplateContent("${value?date?date}");
                AddTemplateVariable("value", new DateTimeOffset(2000, 1, 2, 1, 2, 3, TimeSpan.Zero));

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("Sunday, January 02, 2000"));
            }

            [Test]
            public void Assure_the_long_date_representation_is_returned_for_a_datetime()
            {
                SetTemplateContent("${value?datetime?date}");
                AddTemplateVariable("value", new DateTimeOffset(2000, 1, 2, 1, 2, 3, TimeSpan.Zero));

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("Sunday, January 02, 2000"));
            }

            [Test]
            public void Assure_a_TemplateException_is_thrown_for_a_time()
            {
                SetTemplateContent("${value?time?date}");
                AddTemplateVariable("value", new DateTimeOffset(2000, 1, 2, 1, 2, 3, TimeSpan.Zero));

                Assert.That(
                    () => ProcessTemplate(),
                    Throws.Exception.TypeOf<TemplateException>().
                    With.Message.EqualTo("Cannot convert TIME into DATE"));
            }

            [Test]
            public void Assure_a_default_format_date_string_can_be_converted()
            {
                SetTemplateContent("${value?date}");
                AddTemplateVariable("value", "Wednesday, December 21, 2112");

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("Wednesday, December 21, 2112"));
            }

            [Test]
            public void Assure_a_custom_format_date_string_can_be_converted()
            {
                SetTemplateContent("${value?date('dd - MM - yyyy')}");
                AddTemplateVariable("value", "21 - 12 - 2112");

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("Wednesday, December 21, 2112"));
            }
        }

        [TestFixture]
        public class When_processing_a_datetime_builtin : TemplateTestsBase
        {
            [Test]
            public void Assure_the_full_date_long_time_representation_is_returned_for_a_DateTimeOffset()
            {
                SetTemplateContent("${value?datetime}");
                AddTemplateVariable("value", new DateTimeOffset(2000, 1, 2, 1, 2, 3, TimeSpan.Zero));

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("Sunday, January 02, 2000 1:02:03 AM"));
            }

            [Test]
            public void Assure_a_TemplateException_is_thrown_for_a_date()
            {
                SetTemplateContent("${value?date?datetime}");
                AddTemplateVariable("value", new DateTimeOffset(2000, 1, 2, 1, 2, 3, TimeSpan.Zero));

                Assert.That(
                    () => ProcessTemplate(),
                    Throws.Exception.TypeOf<TemplateException>().
                    With.Message.EqualTo("Cannot convert DATE into DATETIME"));
            }

            [Test]
            public void Assure_the_full_date_long_time_representation_is_returned_for_a_datetime()
            {
                SetTemplateContent("${value?datetime?datetime}");
                AddTemplateVariable("value", new DateTimeOffset(2000, 1, 2, 1, 2, 3, TimeSpan.Zero));

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("Sunday, January 02, 2000 1:02:03 AM"));
            }

            [Test]
            public void Assure_a_TemplateException_is_thrown_for_a_time()
            {
                SetTemplateContent("${value?time?datetime}");
                AddTemplateVariable("value", new DateTimeOffset(2000, 1, 2, 1, 2, 3, TimeSpan.Zero));

                Assert.That(
                    () => ProcessTemplate(),
                    Throws.Exception.TypeOf<TemplateException>().
                    With.Message.EqualTo("Cannot convert TIME into DATETIME"));
            }

            [Test]
            public void Assure_a_default_format_datetime_string_can_be_converted()
            {
                SetTemplateContent("${value?datetime}");
                AddTemplateVariable("value", "Wednesday, December 21, 2112 12:34:56 AM");

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("Wednesday, December 21, 2112 12:34:56 AM"));
            }

            [Test]
            public void Assure_a_custom_format_datetime_string_can_be_converted()
            {
                SetTemplateContent("${value?datetime('dd - MM - yyyy - hh - mm - ss')}");
                AddTemplateVariable("value", "21 - 12 - 2112 - 12 - 34 - 56");

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("Wednesday, December 21, 2112 12:34:56 AM"));
            }
        }

        [TestFixture]
        public class When_processing_a_time_builtin : TemplateTestsBase
        {
            [Test]
            public void Assure_the_long_time_representation_is_returned_for_a_DateTimeOffset()
            {
                SetTemplateContent("${value?time}");
                AddTemplateVariable("value", new DateTimeOffset(2000, 1, 2, 1, 2, 3, TimeSpan.Zero));

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("1:02:03 AM"));
            }

            [Test]
            public void Assure_a_TemplateException_is_thrown_for_a_date()
            {
                SetTemplateContent("${value?date?time}");
                AddTemplateVariable("value", new DateTimeOffset(2000, 1, 2, 1, 2, 3, TimeSpan.Zero));

                Assert.That(
                    () => ProcessTemplate(),
                    Throws.Exception.TypeOf<TemplateException>().
                    With.Message.EqualTo("Cannot convert DATE into TIME"));
            }

            [Test]
            public void Assure_the_long_time_representation_is_returned_for_a_datetime()
            {
                SetTemplateContent("${value?datetime?time}");
                AddTemplateVariable("value", new DateTimeOffset(2000, 1, 2, 1, 2, 3, TimeSpan.Zero));

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("1:02:03 AM"));
            }

            [Test]
            public void Assure_the_long_time_representation_is_returned_for_a_time()
            {
                SetTemplateContent("${value?time?time}");
                AddTemplateVariable("value", new DateTimeOffset(2000, 1, 2, 1, 2, 3, TimeSpan.Zero));

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("1:02:03 AM"));
            }

            [Test]
            public void Assure_a_default_format_time_string_can_be_converted()
            {
                SetTemplateContent("${value?time}");
                AddTemplateVariable("value", "12:34:56 AM");

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("12:34:56 AM"));
            }

            [Test]
            public void Assure_a_custom_format_time_string_can_be_converted()
            {
                SetTemplateContent("${value?time('hh - mm - ss')}");
                AddTemplateVariable("value", "12 - 34 - 56");

                string output = ProcessTemplate();

                Assert.That(output, Is.EqualTo("12:34:56 AM"));
            }
        }
    }
}
// ReSharper enable InconsistentNaming
